package com.itany.nmms.service.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itany.nmms.constant.DictConstant;
import com.itany.nmms.constant.StatusConstant;
import com.itany.nmms.dao.DeptMapper;
import com.itany.nmms.dao.SequenceMapper;
import com.itany.nmms.entity.*;
import com.itany.nmms.exception.*;
import com.itany.nmms.service.DeptService;
import com.itany.nmms.util.ParameterUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author 黄衡熙
 * @version 1.0
 */
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class DeptServiceImpl implements DeptService {
    @Autowired
    private SequenceMapper sequenceMapper;
    @Autowired
    private DeptMapper deptMapper;

    @Override
    public void addFatherDept(String name, String remark, Staff staff) throws RequestParameterErrorException, DeptExistException, LoginDisabledException {
//    参数校验
        if (ParameterUtil.isNull(name) || ParameterUtil.isNull(remark)) {
            throw new RequestParameterErrorException("请求参数有误");
        }
//        判断是否登录
        if (staff == null) {
            throw new LoginDisabledException("登录失效，请重新登录");
        }
//        部门名不可重复
        DeptExample deptExample = new DeptExample();
        deptExample.or()
                .andNameEqualTo(name);
        List<Dept> depts = deptMapper.selectByExample(deptExample);
        if (!depts.isEmpty()) {
            throw new DeptExistException("该部门已存在");
        }

//        开始添加
        Dept dept = new Dept();
        dept.setName(name);
        dept.setRemark(remark);
        dept.setCreateDate(new Date());
        dept.setCreateStaffId(staff.getId());
        dept.setStatus(1);
//        设置默认启用
        dept.setStatus(StatusConstant.DEPT_STATUS_ENABLED);

//        生成部门编号根据前缀去查
        SequenceExample example=new SequenceExample();
        example.or()
                .andNameEqualTo(DictConstant.DEPT_NO_PREFIX);
        List<Sequence> sequences = sequenceMapper.selectByExample(example);
        if(sequences.isEmpty()){
//            如果没找到，说明尚未生成过，因此创建一个初始部门序列号
            Sequence sequence = new Sequence();
            sequence.setName(DictConstant.DEPT_NO_PREFIX);
            sequence.setValue(DictConstant.DEPT_NO_SEQUENCE_INIT_VALUE);
//            添加
            sequenceMapper.insertSelective(sequence);
//            生成部门编号
            dept.setNo(DictConstant.DEPT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        }else{
//            查到后，去除该数据
            Sequence sequence = sequences.get(0);
//            判断序列号是否为最大值,如果为最大值，下一个为初始值,否则加一
            if(DictConstant.DEPT_NO_SEQUENCE_MAX_VALUE.equals(sequence.getValue())){
                sequence.setValue(DictConstant.DEPT_NO_SEQUENCE_INIT_VALUE);
            }else{
                sequence.setValue(ParameterUtil.nextValue(sequence.getValue()));
            }

//            执行修改操作
            sequenceMapper.updateByPrimaryKeySelective(sequence);
            dept.setNo(DictConstant.DEPT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        }
//        添加部门信息
        deptMapper.insertSelective(dept);

    }

    @Override
    public void addSonDept(String fatherId, String name, String remark, Staff staff) throws RequestParameterErrorException, LoginDisabledException, DeptExistException {
        if (ParameterUtil.isNull(fatherId)||ParameterUtil.isNull(name) || ParameterUtil.isNull(remark)) {
            throw new RequestParameterErrorException("请求参数有误");
        }
//        判断是否登录
        if (staff == null) {
            throw new LoginDisabledException("登录失效，请重新登录");
        }
//        部门名不可重复
        DeptExample deptExample = new DeptExample();
        deptExample.or()
                .andNameEqualTo(name);
        List<Dept> depts = deptMapper.selectByExample(deptExample);
        if (!depts.isEmpty()) {
            throw new DeptExistException("该部门已存在");
        }

//        开始添加
        Dept dept = new Dept();
        dept.setName(name);
        dept.setRemark(remark);
        dept.setCreateDate(new Date());
        dept.setCreateStaffId(staff.getId());
        dept.setStatus(1);
//        设置默认启用
        dept.setStatus(StatusConstant.DEPT_STATUS_ENABLED);
//        设置上级部门编号
        dept.setFatherDeptId(Integer.parseInt(fatherId));

//        生成部门编号根据前缀去查
        SequenceExample example=new SequenceExample();
        example.or()
                .andNameEqualTo(DictConstant.DEPT_NO_PREFIX);
        List<Sequence> sequences = sequenceMapper.selectByExample(example);
        if(sequences.isEmpty()){
//            如果没找到，说明尚未生成过，因此创建一个初始部门序列号
            Sequence sequence = new Sequence();
            sequence.setName(DictConstant.DEPT_NO_PREFIX);
            sequence.setValue(DictConstant.DEPT_NO_SEQUENCE_INIT_VALUE);
//            添加
            sequenceMapper.insertSelective(sequence);
//            生成部门编号
            dept.setNo(DictConstant.DEPT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        }else{
//            查到后，去除该数据
            Sequence sequence = sequences.get(0);
//            判断序列号是否为最大值,如果为最大值，下一个为初始值,否则加一
            if(DictConstant.DEPT_NO_SEQUENCE_MAX_VALUE.equals(sequence.getValue())){
                sequence.setValue(DictConstant.DEPT_NO_SEQUENCE_INIT_VALUE);
            }else{
                sequence.setValue(ParameterUtil.nextValue(sequence.getValue()));
            }

//            执行修改操作
            sequenceMapper.updateByPrimaryKeySelective(sequence);
            dept.setNo(DictConstant.DEPT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        }
//        添加部门信息
        deptMapper.insertSelective(dept);
    }
    @Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
    @Override
    public PageInfo<Dept> findPage(String pageNo, String pageSize) {
        if(ParameterUtil.isNull(pageNo)){
            pageNo=DictConstant.DEPT_DEFAULT_PAGE_NO;
        }
        if(ParameterUtil.isNull(pageSize)){
            pageSize=DictConstant.DEPT_DEFAULT_PAGE_SIZE;
        }
//        分页三部取
        PageHelper.startPage(Integer.parseInt(pageNo),Integer.parseInt(pageSize));
        List<Dept> depts=deptMapper.selectAll();
        PageInfo<Dept> deptPage=new PageInfo<>(depts);
        return deptPage;
    }
    @Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
    @Override
    public Dept findById(String id) throws RequestParameterErrorException {
        if(ParameterUtil.isNull(id)){
            throw new RequestParameterErrorException("请参数有误");
        }
        return deptMapper.selectByPrimaryKey(Integer.parseInt(id));
    }

    @Override
    public void modifyDept(String id, String name, String remark) throws RequestParameterErrorException, DeptExistException {
        if(ParameterUtil.isNull(id)||ParameterUtil.isNull(name)||ParameterUtil.isNull(remark)){
            throw new RequestParameterErrorException("请求参数有误");

        }
//        判重
        DeptExample example=new DeptExample();
        example.or()
                .andNameEqualTo(name)
                .andIdNotEqualTo(Integer.parseInt(id));
        List<Dept>depts=deptMapper.selectByExample(example);
        if(!depts.isEmpty()){
            throw new DeptExistException("该部门已经存在");
        }
//        修改
        Dept dept=new Dept();
        dept.setId(Integer.parseInt(id));
        dept.setName(name);
        dept.setRemark(remark);
        deptMapper.updateByPrimaryKeySelective(dept);
    }

//    启用部门
    @Override
    public void enabledDept(String id) throws RequestParameterErrorException, DeptStatusException {
        if(ParameterUtil.isNull(id)){
            throw new RequestParameterErrorException("请求参数有误");
        }
//        启用只有当上级部门是启用状态时才可以启用，因此需要获取上级部门
//        根据当前主键获取当前部门信息
        Dept dept=deptMapper.selectByPrimaryKey(Integer.parseInt(id));
//        根据当前部门中所属上级部门的编号再次根据主键查询,当前部门的父部门信息
        Dept fatherDept=deptMapper.selectByPrimaryKey(dept.getFatherDeptId());
//        存在上部门，且状态为禁用，此时无法启用当前部门，抛出异常
        if(fatherDept !=null && fatherDept.getStatus()==StatusConstant.DEPT_STATUS_DISABLED){
            throw new DeptStatusException("请先启用上级部门");
        }else{
//            正常启用
            dept.setStatus(StatusConstant.DEPT_STATUS_ENABLED);
//            修改
            deptMapper.updateByPrimaryKeySelective(dept);
        }

    }


//    禁用部门
    @Override
    public void disabledDept(String id) throws RequestParameterErrorException {
        if(ParameterUtil.isNull(id)){
            throw new RequestParameterErrorException("请求参数有误");
        }
//禁用当前部门的同时该部门下的所有子孙部门一同被禁用
        Dept dept=deptMapper.selectByPrimaryKey(Integer.parseInt(id));
//        禁用
        dept.setStatus(StatusConstant.DEPT_STATUS_DISABLED);
        deptMapper.updateByPrimaryKeySelective(dept);

//        查找子部门，所有上级部门的father_dept_id与当前部门的id相等的部门都属于子部门
        DeptExample example=new DeptExample();
        example.or()
                .andFatherDeptIdEqualTo(dept.getId());
//        查询到的所有的子部门
        List<Dept> sonDepts=deptMapper.selectByExample(example);
//        对子部门递归禁用操作
        for(Dept sonDept : sonDepts){
            disabledDept(sonDept.getId().toString());
        }

    }
//只读事务
    @Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
    @Override
    public List<Dept> findAll() {
        return deptMapper.selectByExample(new DeptExample());
    }

}
